package cn.jdemo.jsystem.management;

import javax.management.ObjectName;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.util.List;

/**
 * @see ManagementFactory#getGarbageCollectorMXBeans()
 *
 * (1)CMD命令查看安装的jvm的优化参数: java -XX:+PrintCommandLineFlags -version
 *
 *  输出内容:
 * -XX:InitialHeapSize=263516480 -XX:MaxHeapSize=4216263680 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers
 * -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
 * java version "1.8.0_162"
 * Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
 * Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
 *
 * (2)JVM的垃圾回收机制有下面几种：
 * 年轻态几种垃圾收集方式：
 *   Serial (复制) 是一种STW(stop-the-world), 使用单个GC线程进行复制收集,将幸存对象从 Eden复制到幸存Survivor空间，并且在幸存Survivor空间之间复制，直到它决定这些对象已经足够长了，在某个点一次性将它们复制到旧生代old generation.
 *   Parallel Scavenge (PS Scavenge)是一种STW, 使用多个GC线程实现复制收集。如同上面复制收集一样，但是它是并行使用多个线程。
 *   ParNew是一种STW, 使用多个GC线程实现的复制收集，区别于"Parallel Scavenge"在于它与CMS可搭配使用，它也是并行使用多个线程，内部有一个回调功能允许旧生代操作它收集的对象。
 *
 * 旧生代几种垃圾收集方式：
 *   Serial Old (MarkSweepCompact) 是一种stop-the-world, 使用单个线程进行mark-sweep-compact(标志-清扫-压缩)收集。
 *   Parallel Old (PS MarkSweep) 是一种使用多个GC线程压缩收集。
 *   ConcurrentMarkSweep (CMS) 是最并行，低暂停的收集器。垃圾回收算法在后台不会暂停应用线程情况下实现大部分垃圾回收工作。
 *   G1 使用 'Garbage First' 算法将堆空间划分为许多小空间。是一种跨年轻态和旧生代的回收。Java 7以后支持。
 *
 * @date 2020/12/21
 */
public class Demo02_getGarbageCollectorMXBeans {
    public static void main(String[] args) {
        test01();
    }

    /**
     * 输出内容:
     * objectName: java.lang:type=GarbageCollector,name=PS Scavenge
     * name: PS Scavenge
     * memoryPoolNames: [Ljava.lang.String;@5594a1b5
     * collectionTime: 0
     * collectionCount: 0
     * objectName: java.lang:type=GarbageCollector,name=PS MarkSweep
     * name: PS MarkSweep
     * memoryPoolNames: [Ljava.lang.String;@6a5fc7f7
     * collectionTime: 0
     * collectionCount: 0
     *
     * 补充:
     * PS MarkSweep收集器来进行老年代收集(PS MarkSweep与Serial Old实现非常接近，因此官方的许多资料都直接以Serial Old代替PS MarkSweep进行讲解。)
     * (PS Scavenge)：Parallel Scavenge
     */
    public static void test01() {
        List<GarbageCollectorMXBean> GarbageMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
        GarbageMXBeans.stream().forEach((garbageMxBean)->{
            ObjectName objectName = garbageMxBean.getObjectName();
            String name = garbageMxBean.getName();
            String[] memoryPoolNames = garbageMxBean.getMemoryPoolNames();
            long collectionTime = garbageMxBean.getCollectionTime();
            long collectionCount = garbageMxBean.getCollectionCount();
            System.out.println("objectName: "+objectName);
            System.out.println("name: "+name);
            System.out.println("memoryPoolNames: "+memoryPoolNames);
            System.out.println("collectionTime: "+collectionTime);
            System.out.println("collectionCount: "+collectionCount);
        });
    }
}
